require 'informer'
require 'uri'
require 'resolv'

class DataInform
	include Informer

	def initialize (& function)
		if block_given? 
			@validator = function
		else
			@validator = Proc.new {return true}
		end
		self.clear!
	end

	def data?
		return @data
	end

	def data= value
		if @validator.call(value)
			@data= value
			self.state= Informer::OK unless self.state? == Informer::WARN
			self.add_notice "Value changed: #{value.inspect}"			
		else
			@data = nil
			self.state= Informer::ERROR
			self.add_notice "Value not valid: #{value.inspect}"
		end
		rescue Exception
			self.state= Informer::ERROR
		  self.add_notice "Error in validator with: #{value.inspect}"
	end
end

class BoolInform < DataInform
	def initialize
	  super {|b| b== true or b==false}
	end
end

class WordInform < DataInform
	def initialize
	  super {|t| t !~ /\W/}
	end
end

class HostnameInform < DataInform
	def initialize
	  super {|h| hostname?(h)}
	end

	def hostname?(addr)
	begin
		uri = URI.parse(addr)
		if uri.class != URI::Generic
			self.state= Informer::WARN
			self.add_notice('You must remove protocol! (http, ftp...)')
			if uri.host != nil
				addr = uri.host
			else
			  addr=addr.split('//')[1]				
			end
		end
		ip=Resolv.getaddress(addr)
		return ip
		rescue URI::InvalidURIError
			self.state= Informer::ERROR
			self.add_notice("hostname?::Error in #{addr}")
			return false
		rescue Exception
			self.state= Informer::ERROR
			self.add_notice("hostname?::Error resolving address? #{addr}")
			return false
	end		
end

end

if __FILE__ == $0
	d = DataInform.new {|x| x>0}
	puts (d.data= 5).to_s
	puts (d.data= -4).to_s
end
